#pragma once

#include <functional>

#include "InputUtil.h"
#include "EventArgs.h"

namespace mgui
{
	class Control
	{
	public:
		Control();
		virtual ~Control();

		void addListener(int eventType, std::function<void (const EventArgs&)> listener);
		void addChild(Control & child);

		

		void draw();
		bool leftButtonDown(const Point & pt);
		bool leftButtonUp(const Point & pt);
		bool mouseMoved(const Point & pt);
		bool keyPressed(const input::KeyEvent & key);

		bool IsVisible;

		// Returns true if set/unset succeed
		bool setExclusiveInputReceiver(Control & control);
		bool unsetExclusiveInputReceiver(Control & control);

		void setRootControl(Control & control);
		

	protected:
		void callListeners(int eventType, const EventArgs & args);

		virtual bool processLButtonDownInside(const Point & pt){ return false; };
		virtual bool processLButtonDownOutside(const Point & pt){ return false; };
		virtual bool processLButtonUpInside(const Point & pt){ return false; };
		virtual bool processLButtonUpOutside(const Point & pt){ return false; };
		virtual bool processMouseMovedInside(const Point & pt){ return false; };
		virtual bool processMouseMovedOutside(const Point & pt){ return false; };
		virtual bool processKeyPressed(const input::KeyEvent & key){ return false; };
		virtual void drawSelf() {};

		void setBounds(const Rect & bounds);

		std::vector< std::pair< int, std::function<void (const EventArgs&)> > > mListeners;
		std::vector< Control* > mChildren;

		Rect mBounds;

		bool mHasBounds;

		// meaningful if this != mRootControl
		Control * mRootControl;
		// meaningful if this == mRootControl (child controls can apply to root control to become exclusive input receiver
		Control * mExclusiveInputReceiver;
	};

}